// Created by Roman Novitsky on 29.06.2009


#region Imported Namespaces


using System.Collections.Generic;
using System.Windows;
using System.Windows.Interop;


#endregion


namespace WtfManager.WindowsNative
{
  public class WindowHookHelper
  {
    #region Fields


    private static readonly Dictionary<Window, HwndSource> HwndSources = new Dictionary<Window, HwndSource>();


    #endregion


    #region Methods


    public static bool AddHook(Window window, HwndSourceHook hookProcesor)
    {
      HwndSource hwndSource = GetHwndSource(window);

      if (hwndSource != null)
      {
        hwndSource.AddHook(hookProcesor);

        return true;
      }

      return false;
    }


    public static bool RemoveHook(Window window, HwndSourceHook hookProcesor)
    {
      HwndSource hwndSource;

      if (HwndSources.ContainsKey(window))
      {
        hwndSource = HwndSources[window];
      }
      else
      {
        return false;
      }

      hwndSource.RemoveHook(hookProcesor);

      return true;
    }


    private static HwndSource GetHwndSource(Window window)
    {
      var windowInteropHelper = new WindowInteropHelper(window);
      HwndSource hwndSource;

      if (HwndSources.ContainsKey(window))
      {
        hwndSource = HwndSources[window];
      }
      else
      {
        hwndSource = HwndSource.FromHwnd(windowInteropHelper.Handle);

        if (hwndSource != null)
        {
          hwndSource.Disposed += HwndSourceDisposed;
          HwndSources.Add(window, hwndSource);
        }
        else
        {
          return hwndSource;
        }
      }

      return hwndSource;
    }

    static void HwndSourceDisposed(object sender, System.EventArgs e)
    {
      Window window = null;

      foreach (KeyValuePair<Window, HwndSource> pair in HwndSources)
      {
        if (pair.Value != sender)
        {
          continue;
        }

        window = pair.Key;
        break;
      }

      if(window != null)
      {
        HwndSources.Remove(window);
      }
    }


    #endregion
  }
}